#ifndef VEC4F
#define VEC4F

#include <cmath>

struct vec4f {

  float x;
  float y;
  float z;
  float w;

  vec4f() : x(0.0), y(0.0), z(0.0), w(0.0) {
  }

  vec4f(float _x, float _y, float _z, float _w) : x(_x), y(_y), z(_z), w(_w) {
  }

  vec4f(const vec4f &b) : x(b.x), y(b.y), z(b.z), w(b.w) {
  }

  vec4f operator-(vec4f b) {
    return vec4f(x - b.x, y - b.y, z - b.z, w - b.w);
  }

  vec4f operator+(vec4f b) {
    return vec4f(x + b.x, y + b.y, z + b.z, w + b.w);
  }

  vec4f operator*(float value) const {
    return vec4f(x * value, y * value, z * value, w * value);
  }

  vec4f operator*(vec4f b) const {
    return vec4f(x * b.x, y * b.y, z * b.z, w * b.w);
  }

  vec4f operator/(float value) const {
    return vec4f(x / value, y / value, z / value, w / value);
  }

  vec4f operator/(vec4f b) const {
    return vec4f(x / b.x, y / b.y, z / b.z, w / b.w);
  }

  float &operator[](int index) {
    if (index == 0) return x;
    else if (index == 1) return y;
    else if (index == 2) return z;
    else return w;
  }

  bool operator==(vec4f b) {
    return (x == b.x && y == b.y && z == b.z && w == b.w);
  }

  bool operator!=(vec4f b) {
    return !(x == b.x && y == b.y && z == b.z && w == b.w);
  }

  float sqrLength(void) const { 
    return x * x + y * y + z * z + w * w; 
  }

  float length(void) const {
    return static_cast<float>(sqrt(this->sqrLength()));
  }
};

#endif